package com.m1905.lib.download;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

import com.m1905.lib.download.listener.DispatchDownloadStatusListener;
import com.m1905.lib.download.listener.DownloadStatusListener;
import com.m1905.lib.download.listener.OnCmdCompletedListener;
import com.m1905.lib.download.model.DataWrapper;
import com.m1905.lib.download.model.DownloadDBItem;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wanghao
 * @date 2023/11/17.
 * @des
 */
public class DownloadManager {

    private final Handler mServiceHandler;
    private final Looper mServiceLooper;

    public static final int CMD_START = 1;
    public static final int CMD_STOP = 2;
    public static final int CMD_DELETE = 3;
    public static final int CMD_INSERT = 4;
    private final DownloadController controller;

    public static DownloadManager getInstance() {
        return Holder.mInstance;
    }

    private static class Holder {
        private static final DownloadManager mInstance = new DownloadManager();
    }

    private DownloadManager() {
        controller = new DownloadController(unionDownloadStatusListener);
        HandlerThread thread = new HandlerThread("DownloadSchedulerThread");
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new Handler(mServiceLooper) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                int status = msg.what;
                switch (status) {
                    case CMD_START:
                        controller.startDownloadList((DataWrapper) msg.obj);
                        break;
                    case CMD_STOP:
                        controller.stopDownloadList((DataWrapper) msg.obj);
                        break;
                    case CMD_DELETE:
                        controller.deleteDownloadList((DataWrapper) msg.obj);
                        break;
                    case CMD_INSERT:
                        controller.insertList((DataWrapper) msg.obj);
                        break;
                }
            }
        };
    }

    public void startDownload(DownloadDBItem item) {
        startDownload(toList(item), null);
    }

    public void startDownload(DownloadDBItem item, OnCmdCompletedListener listener) {
        startDownload(toList(item), listener);
    }

    public void startDownload(List<DownloadDBItem> ls) {
        startDownload(ls, null);
    }

    public void startDownload(List<DownloadDBItem> ls, OnCmdCompletedListener listener) {
        postToDownloadHandler(CMD_START, new DataWrapper(CMD_START, ls, listener));
    }


    public void stopDownload(DownloadDBItem item) {
        stopDownload(toList(item), null);
    }

    public void stopDownload(DownloadDBItem item, OnCmdCompletedListener listener) {
        stopDownload(toList(item), listener);
    }

    public void stopDownload(List<DownloadDBItem> ls) {
        stopDownload(ls, null);
    }

    public void stopDownload(List<DownloadDBItem> ls, OnCmdCompletedListener listener) {
        postToDownloadHandler(CMD_STOP, new DataWrapper(CMD_STOP, ls, listener));
    }

    public void deleteDownload(DownloadDBItem item) {
        deleteDownload(toList(item), null);
    }

    public void deleteDownload(DownloadDBItem item, OnCmdCompletedListener listener) {
        deleteDownload(toList(item), listener);
    }

    public void deleteDownload(List<DownloadDBItem> ls) {
        deleteDownload(ls, null);
    }

    public void deleteDownload(List<DownloadDBItem> ls, OnCmdCompletedListener listener) {
        postToDownloadHandler(CMD_DELETE, new DataWrapper(CMD_DELETE, ls, listener));
    }


    public void insert(List<DownloadDBItem> ls, OnCmdCompletedListener listener) {
        postToDownloadHandler(CMD_INSERT, new DataWrapper(CMD_INSERT, ls, listener));
    }

    public List<DownloadDBItem> getDownloadList() {
        return new ArrayList<>(controller.getDownloadList());
    }

    private final DispatchDownloadStatusListener unionDownloadStatusListener = new DispatchDownloadStatusListener();

    private void postToDownloadHandler(int status, DataWrapper wrapper) {
        Message message = Message.obtain();
        message.what = status;
        message.obj = wrapper;
        mServiceHandler.sendMessage(message);
    }

    private static List<DownloadDBItem> toList(DownloadDBItem item) {
        List<DownloadDBItem> ls = new ArrayList<>();
        ls.add(item);
        return ls;
    }

    public void registerDownloadStatusListener(DownloadStatusListener callBack) {
        unionDownloadStatusListener.registerDownloadStatusListener(callBack);
    }

    public void unregisterDownloadStatusListener(DownloadStatusListener callBack) {
        unionDownloadStatusListener.unregisterDownloadStatusListener(callBack);
    }

    public List<DownloadDBItem> query(int types, int states, String contentId, String episodeId, int limit) {
        return controller.query(types, states, contentId, episodeId, limit <= 0 ? Integer.MAX_VALUE : limit);
    }

}
